home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / pascal / tpl60n19.zip / ARISOURC.ZIP / FASTMUL2.ASM < prev    next >
Assembly Source File  |  1993-01-24  |  8KB  |  166 lines

  1. CODE         SEGMENT BYTE PUBLIC 'CODE'
  2.  
  3.              ASSUME  CS: CODE
  4.  
  5. PUBLIC       RealMulF, RealMulFNoChk, RealMulFNChk2, ShortMul, ShortMulRev
  6. ; DI:..:CL
  7. ; DX:BX:AX
  8.  
  9. ShortMulRev  PROC    NEAR
  10.              XCHG    AX, CX
  11.              MOV     BX, SI
  12.              XCHG    DX, DI
  13. ShortMulRev  ENDP
  14.  
  15. ShortMul     PROC    NEAR
  16.              PUSH    BP                ; save TURBO-framepointer
  17.              XCHG    BX, DI            ; BX = b1, DI = a2
  18.              MOV     BP, DX            ; get sign of multiplicant
  19.              XOR     BP, BX            ; compute sign of result
  20.              AND     BP, 8000h         ; mask out sign bit
  21.              XCHG    AL, CH            ; save b3
  22.              ADD     CL, CH            ; sum of biased exponents
  23.              SBB     CH, CH            ; clear msb
  24.              NEG     CH                ;  and put possible overflow in CH
  25.              OR      CX, BP            ; zap in sign bit
  26.              PUSH    CX                ; save new exponent and sign bit
  27.              XOR     CX, CX            ; clear lo-bytes of a3 and b3
  28.              OR      DH, 80h           ; set implicit bit of multipicand
  29.              OR      BH, 80h           ; set implicit bit of multiplicator
  30.              MOV     SI, DX            ; save a1
  31.              MUL     BX                ; b1 * a3
  32.              MOV     BP, AX            ; generate sticky byte = 0
  33.              XCHG    AX, DX            ; AX = msw of product
  34.              XCHG    AX, DI            ; save msw of product, get a2
  35.              MUL     BX                ; b1 * a2
  36.              XCHG    AX, BX            ; save lsw of product, get b1
  37.              XCHG    DX, SI            ; save msw of product, get a1
  38.              ADD     BX, DI            ; add product
  39.              ADC     SI, CX            ;  to FPA
  40.              MUL     DX                ; b1 * a1
  41.              ADD     AX, SI            ; add product
  42.              ADC     DX, CX            ;  result in DX:AX:BX
  43.              JMP     $end_mantiss      ; handle exponent
  44. $zero_res:   JMP     $zero_prod2       ; result is 0
  45. ShortMul     ENDP
  46.  
  47.              ALIGN   4
  48.  
  49. RealMulF     PROC    NEAR
  50.              OR      CL, CL            ; multiplicator = 0 ?
  51.              JZ      $zero_res         ; result will be 0
  52.  
  53. RealMulFNoChk PROC    NEAR
  54.              OR      AL, AL            ; multiplicand = 0 ?
  55.              JZ      $zero_res         ; result is zero
  56.  
  57. RealMulFNChk2 PROC    NEAR
  58.              PUSH    BP                ; save TURBO-framepointer
  59.              XCHG    BX, DI            ; BX = b1, DI = a2
  60.              MOV     BP, DX            ; get sign of multiplicant
  61.              XOR     BP, BX            ; compute sign of result
  62.              AND     BP, 8000h         ; mask out sign bit
  63.              XCHG    AL, CH            ; save b3
  64.              ADD     CL, CH            ; sum of biased exponents
  65.              SBB     CH, CH            ; clear msb
  66.              NEG     CH                ;  and put possible overflow in CH
  67.              OR      CX, BP            ; zap in sign bit
  68.              PUSH    CX                ; save new exponent and sign bit
  69.              XOR     CX, CX            ; clear lo-bytes of a3 and b3
  70.              OR      DH, 80h           ; set implicit bit of multipicand
  71.              OR      BH, 80h           ; set implicit bit of multiplicator
  72. $full_mult:  XCHG    AL, CH            ; CH = b3, AL = 0
  73.              PUSH    BX                ; save b1
  74.              PUSH    DX                ; save a1
  75.              MOV     BP, DX            ; save a1
  76. ; b1 = BX
  77. ; b2 = SI
  78. ; b3 = CX
  79. ; a1 = DX
  80. ; a2 = DI
  81. ; a3 = AX
  82.              MUL     BX                ; b1 * a3
  83.              XOR     BX, BX            ; clear FPA
  84.              XCHG    AX, CX            ; get b3, save LSW (b1*a3)
  85.              XCHG    DX, BP            ; get a1, save MSW (b1*a3)
  86.              MUL     DX                ; a1 * b3
  87.              ADD     CX, AX            ; add
  88.              ADC     BP, DX            ;  result
  89.              ADC     BX, BX            ;   to FPA
  90.              MOV     AX, SI            ; b2
  91.              MUL     DI                ; a2 * b2
  92.              ADC     CX, AX
  93.              ADC     BP, DX
  94.              ADC     BX, 0
  95.              XOR     CX, CX            ; FPA = CX:BX:BP
  96.              XCHG    AX, SI            ; get b2
  97.              POP     SI                ; get a1
  98.              MUL     SI                ; a1 * b2
  99.              ADD     BP, AX            ; add
  100.              ADC     BX, DX            ;  result
  101.              ADC     CX, CX            ;   to FPA
  102.              XCHG    AX, DI            ; get a2
  103.              POP     DI                ; get b1
  104.              MUL     DI                ; a2 * b1
  105.              ADD     BP, AX            ; add result
  106.              XCHG    AX, DI            ; get a1
  107.              XCHG    CX, SI            ; CX = b1
  108.              MOV     DI, BX            ; FPA = SI:DI:BX
  109.              MOV     BX, BP            ;
  110. $sqr_end:    ADC     DI, DX            ;  to   SI:DI:BX
  111.              ADC     SI, 0             ;   FPA
  112.              MUL     CX                ; a1 * b1
  113.              ADD     AX, DI
  114.              ADC     DX, SI            ; result in DX:AX:BX
  115. $end_mantiss:POP     CX                ; CH = exponent  CL = sign
  116.              XCHG    AX, BX            ; DX:BX:AX = result
  117.              SUB     CX, 81h           ; compute new exponent-1
  118. $div_end:    OR      DX, DX            ; is mantissa normalized ?
  119.              JS      $add_sub_end      ; yes
  120.              ADD     AX, AX            ; no, shift
  121.              ADC     BX, BX            ;  FPA 1 bit
  122.              ADC     DX, DX            ;   to the left
  123.              DEC     CX                ; adjust exponent
  124. $add_sub_end:XOR     SI, SI            ; load zero
  125.              ADC     AX, 80h           ; round
  126.              ADC     BX, SI            ;  up
  127.              ADC     DX, SI            ;   mantissa
  128.              ADC     CX, SI            ; increment exponent if mantissa overfl.
  129. $round_done: POP     BP                ; restore caller's frame pointer
  130.              TEST    CH, 40H           ; test if (exponent-1) negative
  131.              JNZ     $zero_prod2       ; yes, underflow, return zero
  132.              AND     DH, 7Fh           ; force MSB of mantissa to 0
  133.              INC     CX                ; new exponent
  134.              MOV     AL, CL            ; store exponent
  135.              OR      DH, CH            ; fill in sign bit
  136.              SHR     CH, 1             ; test if exponent overflow (> FFh)
  137.              RET                       ; done
  138. $zero_prod2: XOR     AX, AX            ; load
  139.              MOV     BX, AX            ;  a
  140.              CWD                       ;   zero
  141.              RET                       ; done
  142.  
  143. RealMulFNChk2 ENDP
  144. RealMulFNoChk ENDP
  145. RealMulF      ENDP
  146.  
  147.              ALIGN   4
  148.  
  149.              ENDS
  150.  
  151. comment #
  152.              OR      SI, SI            ; b2 = 0 ?
  153.              JZ      $test_short       ; yes, test if b3 = 0
  154.              OR      DI, DI            ; a2 = 0 ?
  155.              JNZ     $full_mult        ; no, use full multiplication
  156.              OR      AH, AH            ; a3 = 0 ?
  157.              JNZ     $full_mult        ; no, use full multiplication
  158.              XCHG    AH, AL            ; swap a3 and b3
  159.              XCHG    DI, SI            ; swap a2 and b2
  160.              XCHG    DX, BX            ; swap a1 and b1
  161. $test_short: OR      AL, AL            ; b3 = 0 ?
  162.              JNZ     $full_mult        ; no, use full multiplication
  163.  
  164. #
  165.              END
  166.